<!DOCTYPE html>
<html>

<head>
  <title>Quarkus - Building my first extension</title>
  <script id="adobe_dtm" src="https://www.redhat.com/dtm.js" type="text/javascript"></script>
  <script src="/assets/javascript/highlight.pack.js" type="text/javascript"></script>
  <META HTTP-EQUIV='Content-Security-Policy' CONTENT="default-src 'none'; script-src 'self' 'unsafe-eval' 'sha256-ANpuoVzuSex6VhqpYgsG25OHWVA1I+F6aGU04LoI+5s=' 'sha256-ipy9P/3rZZW06mTLAR0EnXvxSNcnfSDPLDuh3kzbB1w=' js.bizographics.com https://www.redhat.com assets.adobedtm.com jsonip.com https://ajax.googleapis.com https://www.googletagmanager.com https://www.google-analytics.com https://use.fontawesome.com; style-src 'self' https://fonts.googleapis.com https://use.fontawesome.com; img-src 'self' *; media-src 'self' ; frame-src https://www.googletagmanager.com https://www.youtube.com; frame-ancestors 'none'; base-uri 'none'; object-src 'none'; form-action 'none'; font-src 'self' https://use.fontawesome.com https://fonts.gstatic.com;">
  <META HTTP-EQUIV='X-Frame-Options' CONTENT="DENY">
  <META HTTP-EQUIV='X-XSS-Protection' CONTENT="1; mode=block">
  <META HTTP-EQUIV='X-Content-Type-Options' CONTENT="nosniff">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="Quarkus: Supersonic Subatomic Java">
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:site" content="@QuarkusIO"> 
  <meta name="twitter:creator" content="@QuarkusIO">
  <meta property="og:url" content="https://quarkus.io/guides/building-my-first-extension" />
  <meta property="og:title" content="Quarkus - Building my first extension" />
  <meta property="og:description" content="Quarkus: Supersonic Subatomic Java" />
  <meta property="og:image" content="/assets/images/quarkus_card.png" />
  <link rel="canonical" href="https://quarkus.io/guides/building-my-first-extension">
  <link rel="shortcut icon" type="image/png" href="/favicon.ico" >
  <link rel="stylesheet" href="https://quarkus.io/guides/stylesheet/config.css" />
  <link rel="stylesheet" href="/assets/css/main.css" />
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
  <link rel="alternate" type="application/rss+xml"  href="https://quarkus.io/feed.xml" title="Quarkus">
  <script src="https://quarkus.io/assets/javascript/goan.js" type="text/javascript"></script>
  <script src="https://quarkus.io/assets/javascript/hl.js" type="text/javascript"></script>
</head>

<body class="guides">
  <!-- Google Tag Manager (noscript) -->
  <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NJWS5L"
  height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->

  <div class="nav-wrapper">
  <div class="grid-wrapper">
    <div class="width-12-12">
      <input type="checkbox" id="checkbox" />
      <nav id="main-nav" class="main-nav">
  <div class="container">
    <div class="logo-wrapper">
      
        <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_600px_reverse.png" class="project-logo" title="Quarkus"></a>
      
    </div>
    <label class="nav-toggle" for="checkbox">
      <i class="fa fa-bars"></i>
    </label>
    <div id="menu" class="menu">
      <span>
        <a href="/get-started/" class="">Get Started</a>
      </span>
      <span>
        <a href="/guides/" class="active">Guides</a>
      </span>
      <span>
        <a href="/community/" class="">Community</a>
      </span>
      <span>
        <a href="/support/" class="">Support</a>
      </span>
      <span>
        <a href="/blog/" class="">Blog</a>
      </span>
      <span>
        <a href="https://code.quarkus.io" class="button-cta secondary white">Start Coding</a>
      </span>
    </div>
  </div>
      </nav>
    </div>
  </div>
</div>

  <div class="content">
    <div class="guide">
  <div class="width-12-12">
    <h1 class="text-caps">Quarkus - Building my first extension</h1>
    <div class="hide-mobile toc"><ul class="sectlevel1">
<li><a href="#prerequisites">Prerequisites</a></li>
<li><a href="#solution">Solution</a></li>
<li><a href="#basic-concepts">Basic Concepts</a></li>
<li><a href="#description-of-a-quarkus-extension">Description of a Quarkus extension</a></li>
<li><a href="#quarkus-application-bootstrap">Quarkus Application Bootstrap</a></li>
<li><a href="#maven-setup">Maven setup</a>
<ul class="sectlevel2">
<li><a href="#the-parent-pom-xml">The parent pom.xml</a></li>
<li><a href="#the-deployment-module">The Deployment module</a></li>
<li><a href="#the-runtime-module">The Runtime module</a></li>
</ul>
</li>
<li><a href="#basic-version-of-the-sample-greeting-extension">Basic version of the Sample Greeting extension</a>
<ul class="sectlevel2">
<li><a href="#implementing-the-greeting-feature">Implementing the Greeting feature</a></li>
<li><a href="#deploying-the-greeting-feature">Deploying the Greeting feature</a></li>
<li><a href="#testing-the-greeting-feature">Testing the Greeting feature</a></li>
<li><a href="#debugging-your-extension">Debugging your extension</a></li>
<li><a href="#extension-publication">Extension publication</a></li>
</ul>
</li>
<li><a href="#conclusion">Conclusion</a></li>
</ul></div>
    <div>
      <div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Quarkus extensions enhance your application just as projects dependencies do.
The role of the extensions is to leverage Quarkus paradigms to integrate seamlessly a library into Quarkus architecture - e.g. do more things at build time.
This is how you can use your battle-tested ecosystem and take advantage of Quarkus performance and native compilation.
Go to <a href="https://code.quarkus.io/">code.quarkus.io</a> to get the list of the supported extensions.</p>
</div>
<div class="paragraph">
<p>In this guide we are going to develop the <strong>Sample Greeting Extension</strong>.
The extension will expose a customizable HTTP endpoint which simply greets the visitor.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="title">Disclaimer</div>
To be sure it&#8217;s extra clear you don&#8217;t need an extension to add a Servlet to your application.
This guide is a simplified example to explain the concepts of extensions development.
Keep in mind it&#8217;s not representative of the power of moving things to build time or simplifying the build of native images.
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="prerequisites"><a class="anchor" href="#prerequisites"></a>Prerequisites</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To complete this guide, you need:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>less than 30 minutes</p>
</li>
<li>
<p>an IDE</p>
</li>
<li>
<p>JDK 1.8+ installed with <code>JAVA_HOME</code> configured appropriately</p>
</li>
<li>
<p>Apache Maven 3.6.2+</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="solution"><a class="anchor" href="#solution"></a>Solution</h2>
<div class="sectionbody">
<div class="paragraph">
<p>We recommend that you follow the instructions in the next sections and create the extension step by step.
However, you can go right to the completed example.</p>
</div>
<div class="paragraph">
<p>Clone the Git repository: <code>git clone <a href="https://github.com/quarkusio/quarkus-quickstarts.git" class="bare">https://github.com/quarkusio/quarkus-quickstarts.git</a></code>, or download an <a href="https://github.com/quarkusio/quarkus-quickstarts/archive/master.zip">archive</a>.</p>
</div>
<div class="paragraph">
<p>The solution is located in the <code>getting-started-extension</code> <a href="https://github.com/quarkusio/quarkus-quickstarts/tree/master/getting-started-extension">directory</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="basic-concepts"><a class="anchor" href="#basic-concepts"></a>Basic Concepts</h2>
<div class="sectionbody">
<div class="paragraph">
<p>First things first, we will need to start with some basic concepts.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>JVM mode vs Native mode</p>
<div class="ulist">
<ul>
<li>
<p>Quarkus is first and foremost a Java framework, that means you can develop, package and run classic JAR applications, that&#8217;s what we call <strong>JVM mode</strong>.</p>
</li>
<li>
<p>Thanks to <a href="https://graalvm.org/">GraalVM</a> you can compile your Java application into machine specific code (like you do in Go or C++) and that&#8217;s what we call <strong>Native mode</strong>.</p>
</li>
</ul>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>The operation of compiling Java bytecode into a native system-specific machine code is named <strong>Ahead of Time Compilation</strong> (aka AoT).</p>
</div>
<div class="ulist">
<ul>
<li>
<p>build time vs runtime in classic Java frameworks</p>
<div class="ulist">
<ul>
<li>
<p>The build time corresponds to all the actions you apply to your Java source files to convert them into something runnable (class files, jar/war, native images).
Usually this stage is composed by the compilation, annotation processing, bytecode generation, etc. At this point, everything is under developer&#8217;s scope and control.</p>
</li>
<li>
<p>The runtime is all the actions that happen when you execute your application.
It&#8217;s obviously focused on starting your business-oriented actions but it relies on a lot of technical actions like loading libraries and configuration files, scanning the application&#8217;s classpath, configuring the dependency injection, setting up your Object-Relational Mapping, instantiating your REST controllers, etc.</p>
</li>
</ul>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>Usually, Java frameworks do their bootstrapping during the runtime before actually starting the application "Business oriented layer". During bootstrap, frameworks dynamically collect metadata by scanning the classpath to find configurations, entity definitions, dependency injection binding, etc. in order to instantiate proper objects through reflection. The main consequences are:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Delaying the readiness of your application: you need to wait a couple of seconds before actually serving a business request.</p>
</li>
<li>
<p>Having a peak of resource consumption at bootstrap: in a constrained environment, you will need to size the needed resources based on your technical bootstrap needs rather than your actual business needs.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Quarkus' philosophy is to prevent as much as possible slow and memory intensive dynamic code execution by shifting left these actions and eventually do them during the build time.
A Quarkus extension is a Java piece of code acting as an adapter layer for your favorite library or technology.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="description-of-a-quarkus-extension"><a class="anchor" href="#description-of-a-quarkus-extension"></a>Description of a Quarkus extension</h2>
<div class="sectionbody">
<div class="paragraph">
<p>A Quarkus extension consists of two parts:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The <strong>runtime module</strong> which represents the capabilities the extension developer exposes to the application&#8217;s developer (an authentication filter, an enhanced data layer API, etc).
Runtime dependencies are the ones the users will add as their application dependencies (in Maven POMs or Gradle build scripts).</p>
</li>
<li>
<p>The <strong>deployment module</strong> which is used during the augmentation phase of the build, it describes how to "deploy" a library
following the Quarkus philosophy.
In other words, it applies all the Quarkus optimizations to your application during the build.
The deployment module is also where we prepare things for GraalVM&#8217;s native compilation.</p>
</li>
</ul>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
Users should not be adding the deployment modules of extension as application dependencies. The deployment dependencies are resolved by
Quarkus during the augmentation phase from the runtime dependencies of the application.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>At this point, you should have understood that most of the magic will happen at the Augmentation build time thanks to the deployment module.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="quarkus-application-bootstrap"><a class="anchor" href="#quarkus-application-bootstrap"></a>Quarkus Application Bootstrap</h2>
<div class="sectionbody">
<div class="paragraph">
<p>There are three distinct bootstrap phases of a Quarkus application.</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>Augmentation</strong>. During the build time, the Quarkus extensions will load and scan your application&#8217;s bytecode (including the dependencies) and configuration.
At this stage, the extension can read configuration files, scan classes for specific annotations, etc.
Once all the metadata has been collected, the extensions can pre-process the libraries bootstrap actions like your ORM, DI or REST controllers configurations.
The result of the bootstrap is directly recorded into bytecode and will be part of your final application package.</p>
</li>
<li>
<p><strong>Static Init</strong>. During the run time, Quarkus will execute first a static init method which contains some extensions actions/configurations.
When you will do your native packaging, this static method will be pre-processed during the build time and the objects it has generated will be serialized into the final native executable, so the initialization code will not be executed in the native mode (imagine you execute a Fibonacci function during this phase, the result of the computation will be directly recorded in the native executable).
When running the application in JVM mode, this static init phase is executed at the start of the application.</p>
</li>
<li>
<p><strong>Runtime Init</strong>. Well nothing fancy here, we do classic run time code execution.
So, the more code you run during the two phases above, the faster your application will start.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Now that everything is explained, we can start coding!</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="maven-setup"><a class="anchor" href="#maven-setup"></a>Maven setup</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Quarkus provides <code>create-extension</code> Maven Mojo to initialize your extension project.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">$ mvn io.quarkus:quarkus-maven-plugin:1.7.0.Final:create-extension -N \
    -DgroupId=org.acme \ <i class="conum" data-value="1"></i><b>(1)</b>
    -DartifactId=quarkus-greeting \  <i class="conum" data-value="2"></i><b>(2)</b>
    -Dversion=1.0-SNAPSHOT \ <i class="conum" data-value="3"></i><b>(3)</b>
    -Dquarkus.nameBase="Greeting Extension" <i class="conum" data-value="4"></i><b>(4)</b>
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------&lt; org.apache.maven:standalone-pom &gt;-------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] --------------------------------[ pom ]---------------------------------
[INFO]
[INFO] --- quarkus-maven-plugin:1.7.0.Final:create-extension (default-cli) @ standalone-pom ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.233 s
[INFO] Finished at: 2020-04-22T23:28:15+02:00
[INFO] ------------------------------------------------------------------------</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Project&#8217;s groupId</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>artifactId for the runtime artifact of the extension (the deployment artifactId will be derived from the runtime artifactId by appending <code>-deployment</code>)</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>Project&#8217;s version</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b>4</b></td>
<td>Prefix for the <code>&lt;name&gt;</code> element values in the generated POMs</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Maven has generated a <code>quarkus-greeting</code> directory containing the extension project which consists of the parent <code>pom.xml</code>, the <code>runtime</code> and the <code>deployment</code> modules.</p>
</div>
<div class="sect2">
<h3 id="the-parent-pom-xml"><a class="anchor" href="#the-parent-pom-xml"></a>The parent pom.xml</h3>
<div class="paragraph">
<p>Your extension is a multi-module project. So let&#8217;s start by checking out the parent POM at <code>./quarkus-greeting/pom.xml</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"&gt;
    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;

    &lt;groupId&gt;org.acme&lt;/groupId&gt;
    &lt;artifactId&gt;quarkus-greeting-parent&lt;/artifactId&gt;
    &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
    &lt;name&gt;Greeting Extension - Parent&lt;/name&gt;

    &lt;packaging&gt;pom&lt;/packaging&gt;
    &lt;properties&gt;
        &lt;project.build.sourceEncoding&gt;UTF-8&lt;/project.build.sourceEncoding&gt;
        &lt;project.reporting.outputEncoding&gt;UTF-8&lt;/project.reporting.outputEncoding&gt;
        &lt;maven.compiler.source&gt;1.8&lt;/maven.compiler.source&gt;
        &lt;maven.compiler.target&gt;1.8&lt;/maven.compiler.target&gt;
        &lt;maven.compiler.parameters&gt;true&lt;/maven.compiler.parameters&gt;
        &lt;quarkus.version&gt;1.7.0.Final&lt;/quarkus.version&gt;
        &lt;compiler-plugin.version&gt;3.8.1&lt;/compiler-plugin.version&gt;
    &lt;/properties&gt;
    &lt;modules&gt; <i class="conum" data-value="1"></i><b>(1)</b>
        &lt;module&gt;deployment&lt;/module&gt;
        &lt;module&gt;runtime&lt;/module&gt;
    &lt;/modules&gt;
    &lt;dependencyManagement&gt;
        &lt;dependencies&gt;
            &lt;dependency&gt;
                &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
                &lt;artifactId&gt;quarkus-bom-deployment&lt;/artifactId&gt; <i class="conum" data-value="2"></i><b>(2)</b>
                &lt;version&gt;${quarkus.version}&lt;/version&gt;
                &lt;type&gt;pom&lt;/type&gt;
                &lt;scope&gt;import&lt;/scope&gt;
            &lt;/dependency&gt;
        &lt;/dependencies&gt;
    &lt;/dependencyManagement&gt;
    &lt;build&gt;
        &lt;pluginManagement&gt;
            &lt;plugins&gt;
                &lt;plugin&gt;
                    &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
                    &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
                    &lt;version&gt;${compiler-plugin.version}&lt;/version&gt; <i class="conum" data-value="3"></i><b>(3)</b>
                &lt;/plugin&gt;
            &lt;/plugins&gt;
        &lt;/pluginManagement&gt;
    &lt;/build&gt;
&lt;/project&gt;</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Your extension declares 2 sub-modules <code>deployment</code> and <code>runtime</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>The <code>quarkus-bom-deployment</code> aligns your dependencies with those used by Quarkus during the augmentation phase.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>Quarkus requires a recent version of the Maven compiler plugin supporting the annotationProcessorPaths configuration.</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="the-deployment-module"><a class="anchor" href="#the-deployment-module"></a>The Deployment module</h3>
<div class="paragraph">
<p>Let&#8217;s have a look at the deployment&#8217;s <code>./quarkus-greeting/deployment/pom.xml</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"&gt;
    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
    &lt;parent&gt;
        &lt;groupId&gt;org.acme&lt;/groupId&gt;
        &lt;artifactId&gt;quarkus-greeting-parent&lt;/artifactId&gt;
        &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
        &lt;relativePath&gt;../pom.xml&lt;/relativePath&gt;
    &lt;/parent&gt;

    &lt;artifactId&gt;quarkus-greeting-deployment&lt;/artifactId&gt; <i class="conum" data-value="1"></i><b>(1)</b>
    &lt;name&gt;Greeting Extension - Deployment&lt;/name&gt;

    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
            &lt;artifactId&gt;quarkus-core-deployment&lt;/artifactId&gt; <i class="conum" data-value="2"></i><b>(2)</b>
            &lt;version&gt;${quarkus.version}&lt;/version&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.acme&lt;/groupId&gt;
            &lt;artifactId&gt;quarkus-greeting&lt;/artifactId&gt; <i class="conum" data-value="3"></i><b>(3)</b>
            &lt;version&gt;${project.version}&lt;/version&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;

    &lt;build&gt;
        &lt;plugins&gt;
            &lt;plugin&gt;
                &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
                &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
                &lt;configuration&gt;
                    &lt;annotationProcessorPaths&gt;
                        &lt;path&gt;
                            &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
                            &lt;artifactId&gt;quarkus-extension-processor&lt;/artifactId&gt;  <i class="conum" data-value="4"></i><b>(4)</b>
                            &lt;version&gt;${quarkus.version}&lt;/version&gt;
                        &lt;/path&gt;
                    &lt;/annotationProcessorPaths&gt;
                &lt;/configuration&gt;
            &lt;/plugin&gt;
        &lt;/plugins&gt;
    &lt;/build&gt;

&lt;/project&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The key points are:</p>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>By convention, the deployment module has the <code>-deployment</code> suffix (<code>greeting-deployment</code>).</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>The deployment module depends on the <code>quarkus-core-deployment</code> artifact.
We will see later which dependencies are convenient to add.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>The deployment module also <strong>must</strong> depend on the runtime module.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b>4</b></td>
<td>We add  the <code>quarkus-extension-processor</code> to the compiler annotation processors.</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>In addition to the <code>pom.xml</code> <code>create-extension</code> also generated the <code>org.acme.quarkus.greeting.deployment.GreetingProcessor</code> class.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.quarkus.greeting.deployment;

import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.builditem.FeatureBuildItem;

class GreetingProcessor {

    private static final String FEATURE = "greeting";

    @BuildStep
    FeatureBuildItem feature() {
        return new FeatureBuildItem(FEATURE);
    }

}</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<code>FeatureBuildItem</code> represents a functionality provided by an extension.
The name of the feature gets displayed in the log during application bootstrap.
An extension should provide at most one feature.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Be patient, we will explain the <code>Build Step Processor</code> concept and all the extension deployment API later on.
At this point, you just need to understand that this class explains to Quarkus how to deploy a feature named <code>greeting</code> which is your extension.
In other words, you are augmenting your application to use the <code>greeting</code> extension with all the Quarkus benefits (build time optimization, native support, etc.).</p>
</div>
</div>
<div class="sect2">
<h3 id="the-runtime-module"><a class="anchor" href="#the-runtime-module"></a>The Runtime module</h3>
<div class="paragraph">
<p>Finally <code>./quarkus-greeting/runtime/pom.xml</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"&gt;
    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
    &lt;parent&gt;
        &lt;groupId&gt;org.acme&lt;/groupId&gt;
        &lt;artifactId&gt;quarkus-greeting-parent&lt;/artifactId&gt;
        &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
        &lt;relativePath&gt;../pom.xml&lt;/relativePath&gt;
    &lt;/parent&gt;

    &lt;artifactId&gt;quarkus-greeting&lt;/artifactId&gt;  <i class="conum" data-value="1"></i><b>(1)</b>
    &lt;name&gt;Greeting Extension - Runtime&lt;/name&gt;

    &lt;dependencies&gt;
    &lt;/dependencies&gt;

    &lt;build&gt;
        &lt;plugins&gt;
            &lt;plugin&gt;
                &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
                &lt;artifactId&gt;quarkus-bootstrap-maven-plugin&lt;/artifactId&gt;  <i class="conum" data-value="2"></i><b>(2)</b>
                &lt;version&gt;${quarkus.version}&lt;/version&gt;
                &lt;executions&gt;
                    &lt;execution&gt;
                        &lt;goals&gt;
                            &lt;goal&gt;extension-descriptor&lt;/goal&gt;
                        &lt;/goals&gt;
                        &lt;phase&gt;compile&lt;/phase&gt;
                        &lt;configuration&gt;
                            &lt;deployment&gt;${project.groupId}:${project.artifactId}-deployment:${project.version}
                            &lt;/deployment&gt;
                        &lt;/configuration&gt;
                    &lt;/execution&gt;
                &lt;/executions&gt;
            &lt;/plugin&gt;
            &lt;plugin&gt;
                &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
                &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
                &lt;configuration&gt;
                    &lt;annotationProcessorPaths&gt;
                        &lt;path&gt;
                            &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
                            &lt;artifactId&gt;quarkus-extension-processor&lt;/artifactId&gt; <i class="conum" data-value="3"></i><b>(3)</b>
                            &lt;version&gt;${quarkus.version}&lt;/version&gt;
                        &lt;/path&gt;
                    &lt;/annotationProcessorPaths&gt;
                &lt;/configuration&gt;
            &lt;/plugin&gt;
        &lt;/plugins&gt;
    &lt;/build&gt;
&lt;/project&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The key points are:</p>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>By convention, the runtime module has no suffix (<code>greeting</code>) as it is the artifact exposed to the end user.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>We add  the <code>quarkus-bootstrap-maven-plugin</code> to generate the Quarkus extension descriptor included into the runtime artifact which links it with the corresponding deployment artifact.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>We add  the <code>quarkus-extension-processor</code> to the compiler annotation processors.</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="basic-version-of-the-sample-greeting-extension"><a class="anchor" href="#basic-version-of-the-sample-greeting-extension"></a>Basic version of the Sample Greeting extension</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="implementing-the-greeting-feature"><a class="anchor" href="#implementing-the-greeting-feature"></a>Implementing the Greeting feature</h3>
<div class="paragraph">
<p>The (killer) feature proposed by our extension is to greet the user.
To do so, our extension will deploy, in the user application, a Servlet exposing the HTTP endpoint <code>/greeting</code> which responds to the GET verb with a plain text <code>Hello</code>.</p>
</div>
<div class="paragraph">
<p>The <code>runtime</code> module is where you develop the feature you want to propose to your users, so it&#8217;s time to create our Web Servlet.</p>
</div>
<div class="paragraph">
<p>To use Servlets in your applications you need to have a Servlet Container such as <a href="http://undertow.io">Undertow</a>.
Luckily, <code>quarkus-bom-deployment</code> imported by our parent <code>pom.xml</code> already includes the Undertow Quarkus extension.
All we need to do is add</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
            &lt;artifactId&gt;quarkus-undertow&lt;/artifactId&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>to our <code>./quarkus-greeting/runtime/pom.xml</code>.</p>
</div>
<div class="paragraph">
<p>Now we can create our Servlet <code>org.acme.quarkus.greeting.GreetingServlet</code> in the <code>runtime</code> module.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.quarkus.greeting;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet
public class GreetingServlet extends HttpServlet { <i class="conum" data-value="1"></i><b>(1)</b>

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { <i class="conum" data-value="2"></i><b>(2)</b>
        resp.getWriter().write("Hello");
    }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>As usual, defining a servlet requires to extend <code>javax.servlet.http.HttpServlet</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>Since we want to respond to the HTTP GET verb, we override the <code>doGet</code> method and write <code>Hello</code> in the Servlet response&#8217;s output stream.</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="deploying-the-greeting-feature"><a class="anchor" href="#deploying-the-greeting-feature"></a>Deploying the Greeting feature</h3>
<div class="paragraph">
<p>Quarkus magic relies on bytecode generation at build time rather than waiting for the runtime code evaluation, that&#8217;s the role of your extension&#8217;s <code>deployment</code> module.
Calm down, we know, bytecode is hard and you don&#8217;t want to do it manually, Quarkus proposes a high level API to make your life easier.
Thanks to basic concepts, you will describe the items to produce/consume and the corresponding steps in order to generate the bytecode to produce during the deployment time.</p>
</div>
<div class="paragraph">
<p>The <code>io.quarkus.builder.item.BuildItem</code> concept represents object instances you will produce or consume (and at some point convert into bytecode) thanks to methods annotated with <code>@io.quarkus.deployment.annotations.BuildStep</code> which describe your extension&#8217;s deployment tasks.</p>
</div>
<div class="paragraph">
<p>Go back to the generated <code>org.acme.quarkus.greeting.deployment.GreetingProcessor</code> class.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.quarkus.greeting.deployment;

import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.builditem.FeatureBuildItem;

class GreetingProcessor {

    private static final String FEATURE = "greeting";

    @BuildStep <i class="conum" data-value="1"></i><b>(1)</b>
    FeatureBuildItem feature() {
        return new FeatureBuildItem(FEATURE); <i class="conum" data-value="2"></i><b>(2)</b>
    }

}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td><code>feature()</code> method is annotated with <code>@BuildStep</code> which means it is identified as a deployment task Quarkus will have to execute during the deployment.
<code>BuildStep</code> methods are run concurrently at augmentation time to augment the application.
They use a producer/consumer model, where a step is guaranteed not to be run until all the items that it is consuming have been produced.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td><code>io.quarkus.deployment.builditem.FeatureBuildItem</code> is an implementation of <code>BuildItem</code> which represents the description of an extension.
This <code>BuildItem</code> will be used by Quarkus to display information to the users when the application is starting.</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>There are many <code>BuildItem</code> implementations, each one represents an aspect of the deployment process.
Here are some examples:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>ServletBuildItem</code>: describes a Servlet (name, path, etc.) we want to generate during the deployment.</p>
</li>
<li>
<p><code>BeanContainerBuildItem</code>: describes a container used to store and retrieve object instances during the deployment.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>If you don&#8217;t find a <code>BuildItem</code> for what you want to achieve, you can create your own implementation. Keep in mind that a <code>BuildItem</code> should be as fine-grained as possible, representing a specific part of the deployment.
To create your <code>BuildItem</code> you can extend:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>io.quarkus.builder.item.SimpleBuildItem</code> if you need only a single instance of the item during the deployment (e.g. <code>BeanContainerBuildItem</code>, you only want one container).</p>
</li>
<li>
<p><code>io.quarkus.builder.item.MultiBuildItem</code> if you want to have multiple instances (e.g. <code>ServletBuildItem</code>, you can produce many Servlets during the deployment).</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>It&#8217;s now time to declare our HTTP endpoint. To do so, we need to produce a <code>ServletBuildItem</code>.
At this point, we are sure you understood that if the <code>quarkus-undertow</code> dependency proposes Servlet support for our <code>runtime</code> module, we will need the <code>quarkus-undertow-deployment</code> dependency in our <code>deployment</code> module to have access to the <code>io.quarkus.undertow.deployment.ServletBuildItem</code>.</p>
</div>
<div class="paragraph">
<p>Update the <code>./quarkus-greeting/deployment/pom.xml</code> as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.acme&lt;/groupId&gt;
            &lt;artifactId&gt;quarkus-greeting&lt;/artifactId&gt;
            &lt;version&gt;${project.version}&lt;/version&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
            &lt;artifactId&gt;quarkus-undertow-deployment&lt;/artifactId&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The dependency on <code>quarkus-core-deployment</code> generated by the <code>create-extension</code> mojo can now be removed since
<code>quarkus-undertow-deployment</code> already depends on it.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>We can now update <code>org.acme.quarkus.greeting.deployment.GreetingProcessor</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.quarkus.greeting.deployment;

import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.builditem.FeatureBuildItem;
import org.acme.quarkus.greeting.GreetingServlet;
import io.quarkus.undertow.deployment.ServletBuildItem;

class GreetingProcessor {

    private static final String FEATURE = "greeting";

    @BuildStep
    FeatureBuildItem feature() {
        return new FeatureBuildItem(FEATURE);
    }

    @BuildStep
    ServletBuildItem createServlet() { <i class="conum" data-value="1"></i><b>(1)</b>
      ServletBuildItem servletBuildItem = ServletBuildItem.builder("greeting", GreetingServlet.class.getName())
        .addMapping("/greeting")
        .build(); <i class="conum" data-value="2"></i><b>(2)</b>
      return servletBuildItem;
    }

}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>We add a <code>createServlet</code> method which returns a <code>ServletBuildItem</code> and annotate it with <code>@BuildStep</code>.
Now, Quarkus will process this new task which will result in the bytecode generation of the Servlet registration at build time.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td><code>ServletBuildItem</code> proposes a fluent API to instantiate a Servlet named <code>greeting</code> of type <code>GreetingServlet</code> (it&#8217;s our class provided by our extension <code>runtime</code> module), and map it the <code>/greeting</code> path.</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="testing-the-greeting-feature"><a class="anchor" href="#testing-the-greeting-feature"></a>Testing the Greeting feature</h3>
<div class="paragraph">
<p>When developing a Quarkus extension, you mainly want to test your feature is properly deployed in an application and works as expected.
That&#8217;s why the tests will be hosted in the <code>deployment</code> module.</p>
</div>
<div class="paragraph">
<p>Let&#8217;s add the testing dependencies into the  <code>./quarkus-greeting/deployment/pom.xml</code> and <code>maven-surefire</code> configuration</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">    &lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"&gt;
    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
    &lt;parent&gt;
        &lt;groupId&gt;org.acme&lt;/groupId&gt;
        &lt;artifactId&gt;quarkus-greeting-parent&lt;/artifactId&gt;
        &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
        &lt;relativePath&gt;../pom.xml&lt;/relativePath&gt;
    &lt;/parent&gt;

    &lt;artifactId&gt;quarkus-greeting-deployment&lt;/artifactId&gt;
    &lt;name&gt;Greeting Extension - Deployment&lt;/name&gt;

    &lt;properties&gt;
        &lt;maven.surefire.version&gt;3.0.0-M4&lt;/maven.surefire.version&gt;
    &lt;/properties&gt;

    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.acme&lt;/groupId&gt;
            &lt;artifactId&gt;quarkus-greeting&lt;/artifactId&gt;
            &lt;version&gt;${project.version}&lt;/version&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
            &lt;artifactId&gt;quarkus-undertow-deployment&lt;/artifactId&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
            &lt;artifactId&gt;quarkus-junit5-internal&lt;/artifactId&gt; <i class="conum" data-value="1"></i><b>(1)</b>
            &lt;scope&gt;test&lt;/scope&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;io.rest-assured&lt;/groupId&gt;
            &lt;artifactId&gt;rest-assured&lt;/artifactId&gt; <i class="conum" data-value="2"></i><b>(2)</b>
            &lt;scope&gt;test&lt;/scope&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;

    &lt;build&gt;
        &lt;plugins&gt;
            &lt;plugin&gt;
                &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
                &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
                &lt;configuration&gt;
                    &lt;annotationProcessorPaths&gt;
                        &lt;path&gt;
                            &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
                            &lt;artifactId&gt;quarkus-extension-processor&lt;/artifactId&gt;
                            &lt;version&gt;${quarkus.version}&lt;/version&gt;
                        &lt;/path&gt;
                    &lt;/annotationProcessorPaths&gt;
                &lt;/configuration&gt;
            &lt;/plugin&gt;
            &lt;plugin&gt;
                &lt;artifactId&gt;maven-surefire-plugin&lt;/artifactId&gt; <i class="conum" data-value="3"></i><b>(3)</b>
                &lt;version&gt;${maven.surefire.version}&lt;/version&gt;
                &lt;configuration&gt;
                    &lt;systemPropertyVariables&gt;
                        &lt;java.util.logging.manager&gt;org.jboss.logmanager.LogManager&lt;/java.util.logging.manager&gt;
                        &lt;maven.home&gt;${maven.home}&lt;/maven.home&gt;
                    &lt;/systemPropertyVariables&gt;
                &lt;/configuration&gt;
            &lt;/plugin&gt;
        &lt;/plugins&gt;
    &lt;/build&gt;

&lt;/project&gt;</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Quarkus proposes facilities to test extensions via the <code>quarkus-junit5-internal</code> artifact, in particular the <code>io.quarkus.test.QuarkusUnitTest</code> runner which starts an application with your extension.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>We will use <a href="http://rest-assured.io">RestAssured</a> (massively used in Quarkus) to test our HTTP endpoint.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>In order to not fallback to JUnit 4 legacy mode you need to define a recent version of <code>maven-surefire</code> plugin.</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Currently, the <code>create-extension</code> Maven Mojo does not create the test structure. We&#8217;ll create it ourselves:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">mkdir -p ./quarkus-greeting/deployment/src/test/java/org/acme/quarkus/greeting/deployment</code></pre>
</div>
</div>
<div class="paragraph">
<p>To start testing your extension, create the following <code>org.acme.quarkus.greeting.deployment.GreetingTest</code> test class:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.quarkus.greeting.deployment;

import io.quarkus.test.QuarkusUnitTest;
import io.restassured.RestAssured;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import static org.hamcrest.Matchers.containsString;

public class GreetingTest {

  @RegisterExtension
  static final QuarkusUnitTest config = new QuarkusUnitTest()
    .setArchiveProducer(() -&gt; ShrinkWrap.create(JavaArchive.class)); <i class="conum" data-value="1"></i><b>(1)</b>

  @Test
  public void testGreeting() {
    RestAssured.when().get("/greeting").then().statusCode(200).body(containsString("Hello")); <i class="conum" data-value="2"></i><b>(2)</b>
  }

}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>We register a Junit Extension which will start a Quarkus application with the Greeting extension.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>We verify the application has a <code>greeting</code> endpoint responding to a HTTP GET request with a OK status (200) and a plain text body containing <code>Hello</code></td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Time to test!</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">$ mvn clean test
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] Greeting Extension - Parent                                        [pom]
[INFO] Greeting Extension - Runtime                                       [jar]
[INFO] Greeting Extension - Deployment                                    [jar]
[INFO]
...
[INFO] --- maven-surefire-plugin:3.0.0-M4:test (default-test) @ quarkus-greeting-deployment ---
[INFO]
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running org.acme.quarkus.greeting.deployment.GreetingTest
2020-04-23 13:55:44,612 INFO  [io.quarkus] (main) Quarkus 1.7.0.Final started in 0.395s. Listening on: http://0.0.0.0:8081
2020-04-23 13:55:44,614 INFO  [io.quarkus] (main) Profile test activated.
2020-04-23 13:55:44,614 INFO  [io.quarkus] (main) Installed features: [cdi, quarkus-greeting, servlet]
2020-04-23 13:55:45,876 INFO  [io.quarkus] (main) Quarkus stopped in 0.025s
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 3.609 s - in org.acme.quarkus.greeting.deployment.GreetingTest
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for getting-started-extension 1.0-SNAPSHOT:
[INFO]
[INFO] getting-started-extension .......................... SUCCESS [  0.076 s]
[INFO] Greeting Extension - Parent ........................ SUCCESS [  0.002 s]
[INFO] Greeting Extension - Runtime ....................... SUCCESS [  1.467 s]
[INFO] Greeting Extension - Deployment .................... SUCCESS [  4.099 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  5.745 s
[INFO] Finished at: 2020-01-28T22:40:56+01:00
[INFO] ------------------------------------------------------------------------</code></pre>
</div>
</div>
<div class="paragraph">
<p>Looks good! Congratulations you just finished your first extension.</p>
</div>
</div>
<div class="sect2">
<h3 id="debugging-your-extension"><a class="anchor" href="#debugging-your-extension"></a>Debugging your extension</h3>
<div class="paragraph">
<p><em>If debugging is the process of removing bugs, then programming must be the process of putting them in.</em>
Edsger W. Dijkstra</p>
</div>
<div class="sect3">
<h4 id="debugging-your-application-build"><a class="anchor" href="#debugging-your-application-build"></a>Debugging your application build</h4>
<div class="paragraph">
<p>Since your extension deployment is made during the application build, this process is triggered by your build tool.
That means if your want to debug this phase you need to launch your build tool with the remote debug mode switched one.</p>
</div>
<div class="sect4">
<h5 id="maven"><a class="anchor" href="#maven"></a>Maven</h5>
<div class="paragraph">
<p>You can activate Maven remote debugging by using <code>mvnDebug</code>.
You can launch your application with the following command line:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">mvnDebug clean compile quarkus:dev</code></pre>
</div>
</div>
<div class="paragraph">
<p>By default, Maven will wait for a connection on <code>localhost:8000</code>.
Now, you can run your IDE <code>Remote</code> configuration to attach it to <code>localhost:8000</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="gradle"><a class="anchor" href="#gradle"></a>Gradle</h5>
<div class="paragraph">
<p>You can activate Gradle remote debugging by using the flags <code>org.gradle.debug=true</code> or <code>org.gradle.daemon.debug=true</code> in daemon mode.
You can launch your application with the following command line:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">./gradlew quarkusDev -Dorg.gradle.daemon.debug=true</code></pre>
</div>
</div>
<div class="paragraph">
<p>By default, Maven will wait for a connection on <code>localhost:5005</code>.
Now, you can run your IDE <code>Remote</code> configuration to attach it to <code>localhost:5005</code>.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="debugging-your-extension-tests"><a class="anchor" href="#debugging-your-extension-tests"></a>Debugging your extension tests</h4>
<div class="paragraph">
<p>We have seen together how to test your extension and sometimes things don&#8217;t go so well and you want to debug your tests.
Same principle here, the trick is to enable the Maven Surefire remote debugging in order to attach an IDE <code>Remote</code> configuration.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">$ cd ./greeting
$ mvn clean test -Dmaven.surefire.debug</code></pre>
</div>
</div>
<div class="paragraph">
<p>By default, Maven will wait for a connection on <code>localhost:5005</code>.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="extension-publication"><a class="anchor" href="#extension-publication"></a>Extension publication</h3>
<div class="paragraph">
<p>Now that you just finish to build your first extension you should be eager to use it in a Quarkus application!</p>
</div>
<div class="paragraph">
<p><strong>Classic Maven publication</strong></p>
</div>
<div class="paragraph">
<p>Because your extension produces traditional JARs, the easiest way to share your extension is to publish it to a Maven repository.
Once published you can simply declare it with your project dependencies. Let&#8217;s demonstrate that by creating a simple Quarkus application</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">$mvn io.quarkus:quarkus-maven-plugin:1.7.0.Final:create \
     -DprojectGroupId=org.acme \
     -DprojectArtifactId=greeting-app \
     -DprojectVersion=1.0-SNAPSHOT \
     -DclassName=HelloResource</code></pre>
</div>
</div>
<div class="paragraph">
<p><code>cd</code> into <code>greeting-app</code> and add the dependency on <code>quarkus-greeting</code> extension we created above.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<code>quarkus-greeting</code> extension has to be installed in the local Maven repository to be usable in the application.
</td>
</tr>
</table>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.acme&lt;/groupId&gt;
            &lt;artifactId&gt;quarkus-greeting&lt;/artifactId&gt;
            &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
            &lt;artifactId&gt;quarkus-resteasy&lt;/artifactId&gt;
        &lt;/dependency&gt;
        &lt;!-- the rest of the application dependencies --&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Run the application and notice the <code>Install Features</code> list contains the <code>quarkus-greeting</code> extension.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">$ mvn clean compile quarkus:dev
[INFO] Scanning for projects...
[INFO]
[INFO] ---------------------&lt; org.acme:code-with-quarkus &gt;---------------------
[INFO] Building code-with-quarkus 1.0.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ code-with-quarkus ---
[INFO] Deleting /tmp/code-with-quarkus/target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ code-with-quarkus ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 2 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ code-with-quarkus ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /tmp/code-with-quarkus/target/classes
[INFO]
[INFO] --- quarkus-maven-plugin:1.7.0.Final:dev (default-cli) @ code-with-quarkus ---
Listening for transport dt_socket at address: 5005
__  ____  __  _____   ___  __ ____  ______
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/
 -/ /_/ / /_/ / __ |/ , _/ ,&lt; / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
2020-04-23 14:17:36,137 INFO  [io.quarkus] (Quarkus Main Thread) greeting-app 1.0-SNAPSHOT (powered by Quarkus 1.7.0.Final) started in 0.985s. Listening on: http://0.0.0.0:8080
2020-04-23 14:17:36,140 INFO  [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
2020-04-23 14:17:36,140 INFO  [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, quarkus-greeting, resteasy, servlet]</code></pre>
</div>
</div>
<div class="paragraph">
<p>From an extension developer standpoint the Maven publication strategy is very handy and fast but Quarkus wants to go one step further by also ensuring a reliability of the ecosystem for the people who will use the extensions.
Think about it, we all had a poor Developer Experience with an unmaintained library, an incompatibility between dependencies (and we don&#8217;t even talk about legal issues).
That&#8217;s why there is the Quarkus Platform.</p>
</div>
<div class="paragraph">
<p><strong>Quarkus Platform</strong></p>
</div>
<div class="paragraph">
<p>Quarkus proposes a <code>quarkus-universe-bom</code> which is a certified list of extensions placed under the Quarkus Platform label. From an application developer, the objectives of the platform are:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>To guarantee a supportability of the extension (bugfix, security issues, dependency upgrades)</p>
</li>
<li>
<p>To ease the extension discovery through the Quarkus CLI or <a href="https://code.quarkus.io/" class="bare">https://code.quarkus.io/</a></p>
</li>
<li>
<p>To ensure a global consistency of the extension ecosystem</p>
</li>
</ul>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
<div class="title">Should I publish my extension to the platform?</div>
If you feel your extensions is for you or a limited group, simply publishing to Maven is fine.
If the extension solves a general problem, it is very handy for Quarkus users to see it on <a href="https://code.quarkus.io" class="bare">https://code.quarkus.io</a>.
But this comes with some responsibility for you, keeping it up to date with Quarkus minor releases (every month or so at the moment).
When in doubt, have a conversation with the community in the <a href="https://groups.google.com/forum/#!forum/quarkus-dev">Quarkus Google Group</a>. We can make a collective decision.
</td>
</tr>
</table>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
As for now, the process to propose a new extension is not defined yet.
Your best chance is to present your extension on the <a href="https://groups.google.com/forum/#!forum/quarkus-dev">Quarkus Google Group</a> and wait for an official invitation to join the Quarkus Platform.
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="conclusion"><a class="anchor" href="#conclusion"></a>Conclusion</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Creating new extensions may appear to be an intricate task at first but once you understood the Quarkus game-changer paradigm (build time vs runtime) the structure of an extension makes perfectly sense.</p>
</div>
<div class="paragraph">
<p>As usual, along the path Quarkus simplifies things under the hood (Maven Mojo, bytecode generation or testing) to make it pleasant to develop new features.</p>
</div>
</div>
</div>
    </div>
  </div>
</div>

  </div>

  <div class="content project-footer">
  <div class="footer-section">
    <div class="logo-wrapper">
      <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_reverse.svg" class="project-logo" title="Quarkus"></a>
    </div>
  </div>
  <div class="grid-wrapper">
    <p class="grid__item width-3-12">Quarkus is open. All dependencies of this project are available under the <a href='https://www.apache.org/licenses/LICENSE-2.0' target='_blank'>Apache Software License 2.0</a> or compatible license.<br /><br />This website was built with <a href='https://jekyllrb.com/' target='_blank'>Jekyll</a>, is hosted on <a href='https://pages.github.com/' target='_blank'>Github Pages</a> and is completely open source. If you want to make it better, <a href='https://github.com/quarkusio/quarkusio.github.io' target='_blank'>fork the website</a> and show us what you’ve got.</p>

    
      <div class="width-1-12 project-links">
        <span>Navigation</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="/">Home</a></li>
          
            <li><a href="/guides">Guides</a></li>
          
            <li><a href="/community/#contributing">Contribute</a></li>
          
            <li><a href="/faq">FAQ</a></li>
          
            <li><a href="/get-started">Get Started</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Contribute</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://twitter.com/quarkusio">Follow us</a></li>
          
            <li><a href="https://github.com/quarkusio">GitHub</a></li>
          
            <li><a href="/security">Security&nbsp;policy</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Get Help</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://groups.google.com/forum/#!forum/quarkus-dev">Forums</a></li>
          
            <li><a href="https://quarkusio.zulipchat.com">Chatroom</a></li>
          
        </ul>
      </div>
    

    
      <div class="width-3-12 more-links">
        <span>Quarkus is made of community projects</span>
        <ul class="footer-links">
          
            <li><a href="https://vertx.io/" target="_blank">Eclipse Vert.x</a></li>
          
            <li><a href="https://microprofile.io" target="_blank">Eclipse MicroProfile</a></li>
          
            <li><a href="https://hibernate.org" target="_blank">Hibernate</a></li>
          
            <li><a href="https://netty.io" target="_blank">Netty</a></li>
          
            <li><a href="https://resteasy.github.io" target="_blank">RESTEasy</a></li>
          
            <li><a href="https://camel.apache.org" target="_blank">Apache Camel</a></li>
          
            <li><a href="https://code.quarkus.io/" target="_blank">And many more...</a></li>
          
        </ul>
      </div>
    
  </div>
</div>
  <div class="content redhat-footer">
  <div class="grid-wrapper">
    <span class="licence">
      <i class="fab fa-creative-commons"></i><i class="fab fa-creative-commons-by"></i> <a href="https://creativecommons.org/licenses/by/3.0/" target="_blank">CC by 3.0</a> | <a href="https://www.redhat.com/en/about/privacy-policy">Privacy Policy</a>
    </span>
    <span class="redhat">
      Sponsored by
    </span>
    <span class="redhat-logo">
      <a href="https://www.redhat.com/" target="_blank"><img src="/assets/images/redhat_reversed.svg"></a>
    </span>
  </div>
</div>


  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" integrity="sha384-8gBf6Y4YYq7Jx97PIqmTwLPin4hxIzQw5aDmUg/DDhul9fFpbbLcLh3nTIIDJKhx" crossorigin="anonymous"></script>
  <script type="text/javascript" src="/assets/javascript/mobile-nav.js"></script>
  <script type="text/javascript" src="/assets/javascript/scroll-down.js"></script>
  <script src="/assets/javascript/satellite.js" type="text/javascript"></script>
  <script src="https://quarkus.io/guides/javascript/config.js" type="text/javascript"></script>
  <script src="/assets/javascript/search-filter.js" type="text/javascript"></script>
  <script src="/assets/javascript/back-to-top.js" type="text/javascript"></script>
</body>

</html>
